package com.hivekion.system.controller;

import com.alibaba.fastjson.JSON;
import com.google.code.kaptcha.impl.DefaultKaptcha;
import com.hivekion.common.IP.IPUtils;
import com.hivekion.common.core.SystemConstant;
import com.hivekion.common.entity.vo.LoginInputVo;
import com.hivekion.common.entity.vo.LoginResult;
import com.hivekion.common.entity.vo.LoginUser;
import com.hivekion.common.entity.vo.UserInfoVo;
import com.hivekion.common.exception.BusinessException;
import com.hivekion.common.redis.RedisUtil;
import com.hivekion.common.security.JwtTokenUtils;
import com.hivekion.common.security.SecurityUtils;
import com.hivekion.common.validate.ImageUtil;
import com.hivekion.system.domain.SysUser;
import com.hivekion.system.domain.vo.SysUserModelVo;
import com.hivekion.system.service.ISysUserService;
import io.swagger.annotations.ApiOperation;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.authentication.*;
import org.springframework.security.core.Authentication;
import org.springframework.util.DigestUtils;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.List;

@RestController
public class UserLoginController {

    @Autowired
    private AuthenticationManager authenticationManager;

    // 引入 RedistUtil 工具类
    @Autowired
    private RedisUtil redisUtil;
    @Resource
    private DefaultKaptcha captchaProducer;

    @Autowired
    private ISysUserService userService;

    @Value("${user.default.failsCount}")
    private Integer failsCount;

    /**
     * 登录方法
     *
     * @param loginBody 登录信息
     * @return 结果
     */
    @PostMapping("/login")
    public LoginResult login(HttpServletRequest request, @RequestBody LoginInputVo loginBody)
            throws Exception {
        if (!StringUtils.isNotBlank(loginBody.getClientCode())) {
            throw new BusinessException(500, "客户端编码为空");
        }
        // 判断验证码
        String code = loginBody.getCode();
        if (!StringUtils.isNotBlank(code)) {
            throw new BusinessException(500, "请输入验证码");
        }

        Object o = redisUtil.get(loginBody.getClientCode());
        if (o == null) {
            throw new BusinessException(500, "验证码生成失败");
        }
        String validateCode = o.toString();
        if (!validateCode.equals(code)) {
            throw new BusinessException(500, "验证码错误");
        } else {
            redisUtil.delete(loginBody.getClientCode());
        }
        LoginResult result = new LoginResult();
        result.setLoginTime(System.currentTimeMillis());
        String password = DigestUtils.md5DigestAsHex(loginBody.getPassword().getBytes());
        Authentication authentication = authenticate(loginBody.getUserName(), password);
        String Token = JwtTokenUtils.generateToken(authentication);
        Object obj = authentication.getPrincipal();
        if (obj instanceof LoginUser) {
            LoginUser user = (LoginUser) obj;
            SysUser sysUser = userService.getUserByUserName(user.getUsername());
            sysUser.setFails(0);
            sysUser.setStatus(0);
            userService.saveOrUpdate(sysUser);        // 更新失败次数为0
        }
        String ip = IPUtils.getIpAddr(request);
        redisUtil.setTokenRefresh(Token, JSON.toJSONString(obj), ip);
        result.setToken(Token);
        return result;
    }

    private Authentication authenticate(String username, String password) {
        try {
            Authentication user =
                    authenticationManager.authenticate(
                            new UsernamePasswordAuthenticationToken(
                                    username, password)); // 验证用户名和密码
            return user;
        } catch (DisabledException e) {
            throw new BusinessException(500, "用户被禁用");
        } catch (BadCredentialsException e) {
            SysUser user = userService.getUserByUserName(username);
            if (user.getStatus().equals(1)) {
                throw new BusinessException(500, "用户被禁用,请联系管理员！");
            }
            int fails = 0;
            fails = user.getFails() == null ? 0 : user.getFails().intValue();
            if (failsCount >= fails) {
                fails++;
                user.setFails(fails);
                userService.saveOrUpdate(user);        // 更新失败次数
            } else {
                user.setStatus(1);
                userService.saveOrUpdate(user);        // 停用账户
            }
            throw new BusinessException(500, "密码错误,剩余尝试次数" + (failsCount - fails) + "！");
        }
    }

    /**
     * 登录验证码图片
     */
    @GetMapping("/validateCode")
    public void validateCode(HttpServletRequest request, HttpServletResponse response, String clientCode)
            throws Exception {
        if (!StringUtils.isNotBlank(clientCode)) {
            throw new BusinessException(500, "客户端编码为空");
        }
        String capText = captchaProducer.createText();
        try {
            Object o = redisUtil.get(clientCode);
            if (o != null) {
                redisUtil.delete(clientCode);
            }
        } catch (Exception ex) {
            System.out.print(ex.getMessage());
        }
        redisUtil.set(clientCode, capText, 60);
        ImageUtil.validateCode(
                request, response, captchaProducer, capText, SystemConstant.LOGIN_VALIDATE_CODE);
    }

    @GetMapping("/auth/getUserInfo")
    public UserInfoVo getUserInfo() {
        UserInfoVo infoVo = new UserInfoVo();
        LoginUser user = SecurityUtils.getCurrentLoginUser();
        infoVo.setId(user.getUserId());
        SysUserModelVo modelVo = userService.getInfo(user.getUserId());
        BeanUtils.copyProperties(modelVo, infoVo);
        /*if (user.getUsername().equals("admin")) {
            List<String> permissions = menuService.getMenuList().stream()
                    .map(item -> item.getPerms()).distinct()
                    .collect(Collectors.toList());
            infoVo.setPermissions(permissions);
        } else {
            List<String> permissions = userService.getPermissions(user.getUserId());
            if (permissions.size() == 0) {
                permissions.add("pro:home");
            }
            infoVo.setPermissions(permissions);
        }*/
        List<String> permissions = userService.getPermissions(user.getUserId());
        if (permissions.size() == 0) {
            permissions.add("pro:home");
        }
        infoVo.setPermissions(permissions);
        return infoVo;
    }

    @ApiOperation(value = "微信小程序登陆", notes = "微信小程序登陆接口")
    @GetMapping("/wxlogin")
    public LoginResult wxlogin(String encryptedData, String iv, String session_key, String password)
            throws Exception {
        String phone = "";
        LoginInputVo inputVo = new LoginInputVo();
        inputVo.setCode("0");
        inputVo.setUserName(phone);
        inputVo.setPassword(password);
        // login(inputVo);
        return null;
    }

    @PostMapping("/auth/logout")
    public boolean logout() {
        return true;
    }
}
